package com.zhuoyue.system.service.impl;

import com.zhuoyue.common.annotation.DataScope;
import com.zhuoyue.common.core.domain.CategoryNameAndNum;
import com.zhuoyue.common.core.domain.ChartData;
import com.zhuoyue.common.utils.DateUtils;
import com.zhuoyue.system.domain.po.SelectTimePo;
import com.zhuoyue.system.mapper.*;
import com.zhuoyue.system.service.ISysStatisticService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author zhanghui
 */
@Service
public class SysStatisticServiceImpl implements ISysStatisticService {
    @Autowired
    private TblDeviceMapper deviceMapper;

    @Autowired
    private SysProductManageMapper productManageMapper;

    @Autowired
    private TblGatewayZyMapper gatewayZyMapper;

    @Autowired
    private TblAppUserMapper appUserMapper;

    @Autowired
    private TblGatewayMapper gatewayMapper;

    @Autowired
    private TblAppMessageMapper appMessageMapper;

    @Override
    public List<ChartData> getProductCountChart(String orgCode) {
        // 先查产品类型和数量, 再与所有的类型名称相匹配, 获取产品名称
        List<ChartData> deviceCountChart = deviceMapper.getDeviceCountByOrgCode(orgCode);
        List<CategoryNameAndNum> categoryNameAndNumList = productManageMapper.listCategoryNameAndNum();

        for (ChartData chartData : deviceCountChart) {
            for (CategoryNameAndNum categoryNameAndNum : categoryNameAndNumList) {
                if (categoryNameAndNum.getCategoryNum().equals(chartData.getAxisData())) {
                    chartData.setAxisData(categoryNameAndNum.getCategoryName());
                }
            }
        }
        return deviceCountChart;
    }

    @Override
    public List<ChartData> getUserDeviceChart(String account, String orgCode) {
        // 先根据手机号和组织编码查询该用户的网关ID(可以有多个), 再根据网关ID查询设备数量, 最后查询设备的名称
        List<String> gatewayIdList = gatewayZyMapper.getGatewayIdByAccountAndOrgCode(account, orgCode);
        List<ChartData> deviceCountList = new ArrayList<>();

        boolean flag;
        // 多个网关循环查询, 两个网关下同类型的设备直接修改count值
        for (String gatewayId : gatewayIdList) {
            List<ChartData> deviceChartList = deviceMapper.getDeviceCountByGatewayId(gatewayId);
            // 循环新查到的设备列表
            for (ChartData newChartData : deviceChartList) {
                flag = false;
                // 循环已有的设备列表
                for (ChartData oldChartData : deviceCountList) {
                    // 若原列表中已有该设备, 则修改count值, 并跳出循环
                    if (oldChartData.getAxisData().equals(newChartData.getAxisData())) {
                        oldChartData.setCount(oldChartData.getCount() + newChartData.getCount());
                        flag = true;
                        break;
                    }
                }

                // 若原列表中没有该设备, 则直接添加
                if (!flag) {
                    deviceCountList.add(newChartData);
                }
            }
        }

        if (deviceCountList.size() > 0) {
            List<CategoryNameAndNum> categoryNameAndNumList = productManageMapper.listCategoryNameAndNum();

            for (ChartData chartData : deviceCountList) {
                for (CategoryNameAndNum categoryNameAndNum : categoryNameAndNumList) {
                    if (categoryNameAndNum.getCategoryNum().equals(chartData.getAxisData())) {
                        chartData.setAxisData(categoryNameAndNum.getCategoryName());
                    }
                }
            }
        }

        return deviceCountList;
    }

    @DataScope(deptAlias = "s_d")
    @Override
    public List<ChartData> getUserRegisterRangeTimeChart(SelectTimePo selectTimePo) {
        // 设置开始与结束时间的time
        selectTimePo.setSelectStartTime(DateUtils.getStartTimeOfDay(selectTimePo.getSelectStartTime()));
        selectTimePo.setSelectEndTime(DateUtils.getEndTimeOfDay(selectTimePo.getSelectEndTime()));

        // 需查询的日期字符串
        List<String> dateRangeStrList = DateUtils.getDateRange(selectTimePo.getSelectStartTime(), selectTimePo.getSelectEndTime());
        List<ChartData> registerCountRangeTime = appUserMapper.getRegisterCountRangeTime(selectTimePo);
        return filterChartByTime(dateRangeStrList, registerCountRangeTime);
    }

    @DataScope(deptAlias = "s_d")
    @Override
    public List<ChartData> getDeviceIncreaseRangeTimeChart(SelectTimePo selectTimePo) {
        // 设置开始与结束时间的time
        selectTimePo.setSelectStartTime(DateUtils.getStartTimeOfDay(selectTimePo.getSelectStartTime()));
        selectTimePo.setSelectEndTime(DateUtils.getEndTimeOfDay(selectTimePo.getSelectEndTime()));

        // 需查询的日期字符串
        List<String> dateRangeStrList = DateUtils.getDateRange(selectTimePo.getSelectStartTime(), selectTimePo.getSelectEndTime());
        List<ChartData> registerCountRangeTime = deviceMapper.getDeviceCountRangeTime(selectTimePo);
        return filterChartByTime(dateRangeStrList, registerCountRangeTime);
    }

    @DataScope(deptAlias = "s_d")
    @Override
    public List<ChartData> getGatewayIncreaseRangeTimeChart(SelectTimePo selectTimePo) {
        // 设置开始与结束时间的time
        selectTimePo.setSelectStartTime(DateUtils.getStartTimeOfDay(selectTimePo.getSelectStartTime()));
        selectTimePo.setSelectEndTime(DateUtils.getEndTimeOfDay(selectTimePo.getSelectEndTime()));

        // 需查询的日期字符串
        List<String> dateRangeStrList = DateUtils.getDateRange(selectTimePo.getSelectStartTime(), selectTimePo.getSelectEndTime());
        List<ChartData> registerCountRangeTime = gatewayMapper.getGatewayCountRangeTime(selectTimePo);
        return filterChartByTime(dateRangeStrList, registerCountRangeTime);
    }

    @DataScope(deptAlias = "s_d")
    @Override
    public List<ChartData> getAccountMessageCountRangeTimeChart(SelectTimePo selectTimePo) {
        // 设置开始与结束时间的time
        selectTimePo.setSelectStartTime(DateUtils.getStartTimeOfDay(selectTimePo.getSelectStartTime()));
        selectTimePo.setSelectEndTime(DateUtils.getEndTimeOfDay(selectTimePo.getSelectEndTime()));

        // 需查询的日期字符串
        List<String> dateRangeStrList = DateUtils.getDateRange(selectTimePo.getSelectStartTime(), selectTimePo.getSelectEndTime());
        List<ChartData> registerCountRangeTime = appMessageMapper.getAccountMessageCountRangeTime(selectTimePo);
        return filterChartByTime(dateRangeStrList, registerCountRangeTime);
    }

    @DataScope(deptAlias = "s_d")
    @Override
    public List<ChartData> getGatewayMessageCountRangeTimeChart(SelectTimePo selectTimePo) {
        // 设置开始与结束时间的time
        selectTimePo.setSelectStartTime(DateUtils.getStartTimeOfDay(selectTimePo.getSelectStartTime()));
        selectTimePo.setSelectEndTime(DateUtils.getEndTimeOfDay(selectTimePo.getSelectEndTime()));

        // 需查询的日期字符串
        List<String> dateRangeStrList = DateUtils.getDateRange(selectTimePo.getSelectStartTime(), selectTimePo.getSelectEndTime());
        List<ChartData> registerCountRangeTime = appMessageMapper.getGatewayMessageCountRangeTime(selectTimePo);
        return filterChartByTime(dateRangeStrList, registerCountRangeTime);
    }

    /**
     * 过滤报表数据, 当前日期没有数据设置为0
     *
     * @param dateStringList        需查询的日期字符串列表
     * @param originalChartDataList 源报表数据
     * @return 目标报表数据
     */
    private List<ChartData> filterChartByTime(List<String> dateStringList, List<ChartData> originalChartDataList) {
        List<ChartData> targetChartDataList = new ArrayList<>();
        // 用于标识当天是否有数据
        boolean flag;
        for (String dateString : dateStringList) {
            flag = false;
            ChartData targetChartData = new ChartData();
            for (ChartData originalChartData : originalChartDataList) {
                // 若当天有数据
                if (originalChartData.getTime().equals(dateString)) {
                    targetChartData.setAxisData(dateString);
                    targetChartData.setCount(originalChartData.getCount());
                    targetChartDataList.add(targetChartData);
                    flag = true;
                }
            }

            // 若当天没数据
            if (!flag) {
                targetChartData.setAxisData(dateString);
                targetChartData.setCount(0);
                targetChartDataList.add(targetChartData);
            }
        }
        return targetChartDataList;
    }
}
